#!/usr/bin/python
# -*- coding: utf-8 -*-

##
# Módulos del sistema
try:
    import sys
except IndexError, error:
    print error
    print "Problemas al cargar los módulos de sistema."

##
# Módulos definidos por nosotros
try:
    import config
except ImportError, error:
    print error
    print "Problemas al cargar los módulos del programa"

class DocumentoLatex:
    """Clase para el manejo del archivo .tex a generar.
    Se encarga de crear el encabezado y escribir cualquier
    sentencia de LaTeX en este."""

    def __init__(self, libro):
        """Inicializador de la clase.
        Crea el diccionario con llave-valor asociando los estilos a sus
        funciones correspondientes"""
        self.libro = libro
        self.estilos = {}
        for k, v in self.libro["estilos"].iteritems():
            self.estilos[k] = eval(v)
        self.salida_actual = open(self.libro["salidatex"], "w")
        self.generar_encabezado()
        self.encoding = ""
        self.numero_capitulo = 0

    def generar_encabezado(self):
        """Genera el encabezado del archivo .tex a partir del archivo
        encabezado.tex que se encuentra en el directorio raiz"""
        temp = open("encabezado.tex", "r").read()
        self.encabezado = temp.replace("#titulo", self.libro["titulo"])
        self.encabezado = self.encabezado.replace("#autor", self.libro["autor"])
        self.encabezado = self.encabezado.replace("#fecha", self.libro["fecha"])
        self.salida_actual.write(self.encabezado)
        self.texto_salida = ""

    def escribir_archivo(self):
        """Escribe el texto previamente procesado por el programa
        al archivo .tex"""
        self.texto_salida = self.texto_salida.encode(self.encoding)
        self.salida_actual.write(self.texto_salida)

    def pie_de_pagina(self, texto):
        """Genera el código LaTeX para un pié de página"""
        self.texto_salida = "\\footnote{%s} " % texto
        self.escribir_archivo()

    def titulo(self, texto):
        """Genera el código LaTeX para un título. En este caso
        hicimos un texto en negrita con dos salto de línea arriba y
        abajo del mismo"""
        self.texto_salida = "\n\n\\textbf{%s}\n\n" % texto
        self.escribir_archivo()

    def verbatim(self, texto):
        """Genera el código LaTeX para texto preformateado (verbatim)"""
        self.texto_salida = "\\begin{verbatim}\n%s\n\\end{verbatim}" % texto
        self.escribir_archivo()

    def controlador_h1(self, texto):
        """Controla si en el texto se encuentra la palabra Chapter.
        Utilizado en HTML para saber si es un capítulo o una sección"""
        if "Chapter" in texto:
            texto = texto.split(". ")[1]
            self.capitulo(texto)
        else:
            self.seccion(texto)

    def abrir_vineta(self):
        """Genera el código LaTeX para abrir el sector en el cual
        se pueden ingresar viñetas (itemize)"""
        self.texto_salida = "\\begin{itemize}\n"
        self.escribir_archivo()

    def cerrar_vineta(self):
        """Genera el código LaTeX para cerrar el sector en el cual
        se pueden ingresar viñetas (itemize)"""
        self.texto_salida = "\\end{itemize}\n"
        self.escribir_archivo()

    def vineta(self, texto):
        """Genera el código LaTeX para ingresar el texto como una viñeta"""
        self.texto_salida = "\\item %s\n" % texto
        self.escribir_archivo()

    def escribir(self, texto, estilo):
        """Según el estilo, determina a qué función se debe llamar
        utilizando el diciconario self.estilos. Luego si el texto no es
        de tipo 'pre' se reemplazan los caracteres especiales"""
        func = self.estilos[estilo]
        if estilo not in ["pre"]:
            texto = self.procesar_texto(texto)
        func(texto)

    def prefacio(self, texto):
        """Genera el código LaTeX para ingresar un capítulo que
        no este numerado"""
        self.texto_salida = "\\chapter*{%s}\n" % texto
        self.escribir_archivo()

    def capitulo(self, texto):
        """Genera el código LaTeX para ingresar un capítulo numerado.
        Previamente intenta dividirlo para quitar el principio, por
        si dice: 'Chapter 1. Text' por ejemplo"""
        self.numero_capitulo += 1
        try:
            self.texto_salida = "\\chapter{%s}\n" % texto.split(". ")[1]
        except IndexError:
            self.texto_salida = "\\chapter{%s}\n" % texto
        self.escribir_archivo()

    def texto(self, texto):
        """Escribe directamente el texto en el archivo, agregando
        un salto de línea antes y uno después"""
        self.texto_salida = "\n%s\n" % texto
        self.escribir_archivo()

    def finalizar(self):
        """Genera el código LaTeX para terminar el documento"""
        self.texto_salida = "\\end{document}"
        self.escribir_archivo()
        self.salida_actual.close()
        print "Exito!"
        sys.exit(0)

    def seccion(self, texto):
        """Genera el código LaTeX para ingresar una sección. Intenta
        dividir el nombre para quitar la primer parte. Comprueba si ya
        se ha ingresado un capítulo numerado para así comenzar a numerar
        las secciones también"""
        try:
            self.texto_salida = "\\section{%s}" % texto.split(". ")[1]
        except IndexError:
            if self.numero_capitulo != 0:
                self.texto_salida = "\\section{%s}" % texto
            else:
                self.texto_salida = "\\section*{%s}" % texto
        self.escribir_archivo()

    def enlace(self, texto):
        """Genera el código LaTeX para un texto con negrita"""
        self.texto_salida = "\\textbf{%s} " % texto
        self.escribir_archivo()

    def procesar_texto(self, texto):
        """Reemplaza los caracteres especiales por lo adecuados en LaTeX.
        Para esto se establece un orden de prioridades para el reemplazo"""
        for k, v in config.primero.iteritems():
            texto = texto.replace(k, v)
        for k, v in config.segundo.iteritems():
            texto = texto.replace(k, v)
        for k, v in config.tercero.iteritems():
            texto = texto.replace(k, v)
        return texto

    def subseccion(self, texto):
        """Genera el código LaTeX para ingresar una subsección"""
        self.texto_salida = "\\subsection{%s}" % texto
        self.escribir_archivo()

    def subsubseccion(self, texto):
        """Genera el código LaTeX para ingresar una sub-subsección"""
        self.texto_salida = "\\subsubsection{%s}" % texto
        self.escribir_archivo()

    def parte(self, texto):
        """Genera el código LaTeX para ingresar una parte"""
        try:
            self.texto_salida = "\\part{%s}" % texto.split(": ")[1]
        except IndexError:
            self.texto_salida = "\\part{%s}" % texto
        self.escribir_archivo()
